/* ==========================================================================
   LOCKSMITH SHARED COMPONENTS  (.ld-*)  ·  linq Brand Kit edition
   --------------------------------------------------------------------------
   Reusable mobile/tablet UI primitives. Loaded globally from base.html.
   Every selector is `.ld-*` so it can't conflict with the legacy chrome.

   Style guide:    docs/MOBILE_STYLE_MIGRATION.md  (palette / typography)
   Brand kit deck: /tmp/brandkit/new-linq-logo/  (full design system)
   In-app reference: /brand-kit

   --- linq Brand Kit palette ----------------------------------------------
     Bone        #F2EBDF   Page background ("paper")
     Bone-2      #E8E1D1   Inputs, alt rows, date tiles
     Panel       #FFFFFF   Card surface (pure white — pops cleanly on cream
                            without adding extra warm tint)
     Rule        #D9D2C2   Hairline border
     Rule-strong #C8C0AD   Hover border
     Ink         #0F1623   Primary text + marks
     Muted       #8A857A   Secondary text
     Faint       #A8A294   Captions, placeholders
     Signal      #EA6A2C   Primary accent (orange)
     Signal-soft #FBE2D2   Active backgrounds (signal tint)
     Ocean       #3B5BDB   Trust / data secondary
     Sage        #1F9D55   Success secondary
     Warn        #FBC97A   Warning (warm gold)
     Bad         #D14848   Error
   --- Typography -----------------------------------------------------------
     Sans (UI):   'Public Sans' 300/400/500/600/700
     Mono (data): 'Archivo Narrow' 300/400/500/600
     Serif (opt): 'Public Sans' 400/600/800
   ========================================================================== */

/* === Canonical brand tokens (linq · brand guidelines · v1.0 · 2026) =====
   Single source of truth for every surface. Hex values copied verbatim
   from the v1.0 PDF page 10. Never paste raw hex into pages — always
   reference `var(--linq-*)` so future drift is impossible. */
:root {
  /* Color */
  --linq-ink:        #0F1623;
  --linq-ink-2:      #1B2230;
  --linq-ink-soft:   #3A4250;
  --linq-orange:     #EA6A2C;
  --linq-orange-dk:  #C9551F;
  --linq-orange-lt:  #FBE2D2;
  --linq-cream:      #F2EBDF;
  --linq-off-white:  #FAF6EE;
  --linq-blue:       #3B5BDB;
  --linq-green:      #1F9D55;
  --linq-red:        #D14848;
  --linq-amber:      #FBC97A;

  /* Type */
  --linq-font-display: 'Public Sans', sans-serif;
  --linq-font-body:    'Public Sans', sans-serif;
  --linq-font-mono:    'Archivo Narrow', sans-serif;

  /* Radii */
  --linq-r-sm:   6px;
  --linq-r-md:  10px;
  --linq-r-lg:  16px;
  --linq-r-pill: 999px;

  /* Spacing — base 4 */
  --linq-s-1:  4px;
  --linq-s-2:  8px;
  --linq-s-3: 12px;
  --linq-s-4: 16px;
  --linq-s-6: 24px;
  --linq-s-8: 32px;

  /* Elevation — soft warm shadows */
  --linq-e-1: 0 1px 2px rgba(15, 22, 35, .06);
  --linq-e-2: 0 8px 24px rgba(15, 22, 35, .08);
  --linq-e-3: 0 32px 80px -20px rgba(15, 22, 35, .35);

  /* Legacy aliases — keep existing pages working without a sweep.
     Every legacy token now resolves to a PDF-canonical value. */
  --ink:       var(--linq-ink);
  --ink-soft:  var(--linq-ink-soft);
  --bone:      var(--linq-cream);
  --panel:     var(--linq-off-white);
  --signal:    var(--linq-orange);
  --ocean:     var(--linq-blue);
  --sage:      var(--linq-green);
  --bad:       var(--linq-red);
  --warn:      var(--linq-amber);
}

/* === Mono helper ============================================== */
.ld-mono { font-family: 'Archivo Narrow', 'Archivo Narrow', ui-, sans-serif, 'SF Mono', sans-serif; }

/* === Page wrapper (.ld-mobile) ==================================
   Only renders at <=1023px; desktop keeps the legacy chrome. Pages
   are responsible for hiding the legacy `.ud-page` sections etc. via
   their own `<style>` so this remains a pure presentation layer. */
.ld-mobile {
  display: none;
}
@media (max-width: 1023px) {
  .ld-mobile {
    display: block;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    width: 100vw;
    background: var(--linq-cream);
    color: var(--linq-ink);
    font-family: 'Public Sans', 'Public Sans', 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    padding-top: env(safe-area-inset-top, 0);
    padding-bottom: calc(7rem + env(safe-area-inset-bottom, 0));
    min-height: 100vh;
  }
}
@media (min-width: 641px) and (max-width: 1023px) {
  .ld-mobile {
    margin-left: auto;
    margin-right: auto;
    width: min(920px, 100vw);
    max-width: 920px;
  }
}

/* === Sticky header ============================================
   Brand v1.0 inverted palette: ONE shared header (the global
   .ld-header) renders on every authenticated page.

   Surface: opaque ink-2 → ink linear gradient with a subtle cream
   dot-grid texture overlaid via a tiny radial-gradient pattern
   (12px tile, 1px dot at 6% cream alpha). Reads as a single dark
   panel up close + as a textured surface from a distance. No
   backdrop-filter — fully opaque, so the gradient + pattern carry
   all the depth. */
.ld-header {
  position: sticky;
  top: 0;
  z-index: 30;
  padding: 8px 16px;
  background:
    radial-gradient(rgba(250, 246, 238, 0.07) 1px, transparent 1px) 0 0 / 12px 12px,
    linear-gradient(180deg, var(--linq-ink-2, #1B2230) 0%, var(--linq-ink, #0F1623) 100%);
  border-bottom: 1px solid rgba(250, 246, 238, 0.08);
  transition: background .2s, border-color .2s;
  display: flex;
  align-items: center;
  gap: 10px;
  isolation: isolate;
}
.ld-header.is-scrolled {
  border-bottom-color: rgba(250, 246, 238, 0.14);
}

/* Cream-on-ink text + chip overrides. !important to defeat any
   page-level overrides that previously themed icons for cream
   surfaces (those targeted .ld-icon-btn directly with same or
   lower specificity, leaving the icon glyph rendered ink-on-ink). */
.ld-header .ld-brand,
.ld-header .ld-brand-word { color: var(--linq-cream) !important; }
.ld-header .ld-back-btn { color: var(--linq-cream) !important; }
.ld-header .ld-back-btn:active { background: rgba(250, 246, 238, 0.10); }
.ld-header .ld-header-title { color: var(--linq-cream) !important; }
.ld-header .ld-header-name {
  color: rgba(250, 246, 238, 0.62) !important;
  border-left-color: rgba(250, 246, 238, 0.18);
}
.ld-header .ld-icon-btn {
  background: rgba(250, 246, 238, 0.08) !important;
  border: 1px solid rgba(250, 246, 238, 0.18) !important;
  color: var(--linq-cream) !important;
}
.ld-header .ld-icon-btn i { color: var(--linq-cream) !important; }
.ld-header .ld-icon-btn:active { background: rgba(250, 246, 238, 0.16) !important; }
.ld-header .ld-icon-btn .ld-bell-dot {
  background: var(--linq-orange) !important;
  box-shadow: 0 0 0 1.5px var(--linq-ink);
}

/* Global variant — rendered directly by base.html as the default
   mobile_header. Internal page-owned `.ld-header` partials sit inside
   `.ld-mobile` (which is `display: none` on desktop) and hide for free,
   but the global header lives outside that wrapper, so we gate it
   here. Mobile + tablet only; desktop chrome is the left sidebar.

   The dark/glass theme + cream chip overrides now live on the base
   `.ld-header` rule above so every internal page header (customers /
   jobs / invoicing / calendar / inbox / dashboard mobile partials)
   matches the global header automatically. Only the global-specific
   behaviour (icon-cluster auto margin) lives here. */
@media (min-width: 1024px) {
  .ld-header--global { display: none; }
}

/* Brand wordmark — canonical linq mark (q-glyph SVG) + lowercase
   "linq" wordmark in Space Grotesk. The SVG already carries the
   orange tab, so the legacy `::after` square is unnecessary and
   would double-render. Pages that emit just a text node (no <img>)
   still get the inline `.ld-brand-dot` square as a fallback. */
.ld-brand {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-family: 'Public Sans', 'Public Sans', system-ui, sans-serif;
  /* Brand v1.0: wordmark is Public Sans 800. The in-app header was
     rendering at 600 (semi-bold) which read as visibly lighter than
     the marketing site's lockup. */
  font-weight: 800;
  font-size: 20px;
  letter-spacing: -0.045em;
  line-height: 1;
  color: var(--linq-ink);
  text-decoration: none;
  text-transform: lowercase;
}
.ld-brand-mark {
  height: 1.4em;
  width: auto;
  display: block;
  flex-shrink: 0;
}
.ld-brand-word {
  display: inline-block;
}
/* Legacy fallback for places that render `<a class="ld-brand">linq</a>`
   without the SVG mark — keep an orange circle via ::after to echo the
   v3 chain mark's accent (and the wordmark's orange period). */
.ld-brand:not(:has(.ld-brand-mark))::after {
  content: '';
  display: inline-block;
  width: 6px; height: 6px;
  margin-left: 4px;
  border-radius: 50%;
  background: var(--linq-orange);
}
/* Inline orange dot variant (fallback for tight headers where the
   SVG mark doesn't fit). Circle, not square — matches the v3 chain. */
.ld-brand-dot {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--linq-orange);
  margin-left: 3px;
}
.ld-brand .ld-brand-dot { display: none; }

.ld-header-title {
  font-family: 'Public Sans', 'Public Sans', system-ui, sans-serif;
  font-size: 17px; font-weight: 600; letter-spacing: -0.02em;
  color: var(--linq-ink); margin: 0;
}
.ld-header-name {
  display: none;
  margin-left: 6px;
  padding-left: 10px;
  border-left: 1px solid #C8C0AD;
  font-size: 11px; font-weight: 500;
  color: #8A857A;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-family: 'Archivo Narrow', sans-serif;
}
.ld-header.is-scrolled .ld-header-name { display: inline-flex; align-items: center; }
.ld-header-spacer { flex: 1; }
/* Push the icon cluster (call + bell) to the right edge of the global
   header. On tablet 641-1023px the .lq-cmdbar--sticky has flex:1 and
   already consumes the gap; on small phones ≤640px the cmdbar is
   display:none, so without this auto margin the brand and icons
   collapse together at the left.

   `:first-of-type` would have matched `.ld-brand` (also an <a>) instead
   of the icon, so use the sibling-combinator trick: every .ld-icon-btn
   gets margin-left:auto, then any .ld-icon-btn preceded by another
   .ld-icon-btn sibling resets to 0 — net effect: only the first icon
   button in the header carries the auto margin. */
.ld-header--global .ld-icon-btn { margin-left: auto; }
.ld-header--global .ld-icon-btn ~ .ld-icon-btn { margin-left: 0; }
.ld-icon-btn {
  position: relative;
  width: 34px; height: 34px;
  border-radius: 8px;
  background: #FFFFFF;
  border: 1px solid #D9D2C2;
  color: var(--linq-ink);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: background .15s, border-color .15s;
}
.ld-icon-btn:active { background: #E8E1D1; }
.ld-icon-btn .ld-bell-dot {
  position: absolute; top: 6px; right: 6px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--linq-red);
  box-shadow: 0 0 0 1.5px #FFFFFF;
}
.ld-back-btn {
  background: none; border: none;
  color: var(--linq-ink);
  font-size: 18px; cursor: pointer;
  padding: 0; margin-right: 4px;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
  -webkit-tap-highlight-color: transparent;
}
.ld-back-btn:active { background: #E8E1D1; }

/* === Inline search (lives in the header row) =================== */
.ld-search-inline {
  display: none;
  flex: 1;
  align-items: center;
  gap: 8px;
}
.ld-header.is-search-open > :not(.ld-search-inline) { display: none; }
.ld-header.is-search-open .ld-search-inline { display: flex; }
.ld-search-input {
  flex: 1;
  background: #E8E1D1;
  border: 1px solid #D9D2C2;
  border-radius: 8px;
  padding: 9px 11px;
  font: 500 14px/1.2 'Public Sans', 'Public Sans', system-ui, sans-serif;
  color: var(--linq-ink);
  outline: none;
  min-width: 0;
  -webkit-tap-highlight-color: transparent;
}
.ld-search-input::placeholder { color: #A8A294; }
.ld-search-input:focus { border-color: var(--linq-orange); background: #FFFFFF; }
.ld-search-cancel {
  background: none; border: none; color: #8A857A;
  font: 500 13px 'Public Sans', 'Public Sans', system-ui, sans-serif;
  padding: 6px 4px; cursor: pointer; flex-shrink: 0;
}
.ld-search-wrap {
  max-height: 0;
  overflow: hidden;
  transition: max-height .25s ease;
  background: #FFFFFF;
  position: sticky;
  top: 58px;
  z-index: 29;
  border-bottom: 1px solid transparent;
}
.ld-search-wrap.is-open {
  max-height: 70vh;
  border-bottom-color: #D9D2C2;
}
.ld-search-inner { padding: 8px 16px 12px; }
.ld-search-results { display: flex; flex-direction: column; gap: 4px; max-height: calc(70vh - 32px); overflow-y: auto; }
.ld-search-row-item {
  display: flex; align-items: center; gap: 11px;
  padding: 8px 6px; border-radius: 8px; text-decoration: none; color: var(--linq-ink);
  -webkit-tap-highlight-color: transparent;
}
.ld-search-row-item:active { background: #E8E1D1; }
.ld-search-tile {
  width: 30px; height: 30px; border-radius: 7px; background: #E8E1D1;
  display: flex; align-items: center; justify-content: center;
  color: #8A857A; flex-shrink: 0;
}
.ld-search-row-main { flex: 1; min-width: 0; }
.ld-search-row-title { font-size: 13px; font-weight: 500; color: var(--linq-ink); line-height: 1.3; }
.ld-search-row-sub { font-size: 11px; color: #A8A294; font-family: 'Archivo Narrow', sans-serif; margin-top: 1px; }
.ld-search-empty { padding: 16px 6px; font-size: 12.5px; color: #A8A294; }

/* === Page hero / greeting ===================================== */
.ld-greet { padding: 16px 16px 14px; }
.ld-greet-h {
  font-family: 'Public Sans', 'Public Sans', system-ui, sans-serif;
  font-size: 26px; font-weight: 600; letter-spacing: -0.025em;
  color: var(--linq-ink); margin: 0;
}
.ld-greet-date {
  font-size: 11px; font-weight: 500; color: #8A857A;
  letter-spacing: 0.06em; text-transform: uppercase;
  margin-top: 4px;
  font-family: 'Archivo Narrow', sans-serif;
}
.ld-greet-sub { margin-top: 6px; font-size: 12.5px; color: #8A857A; }
.ld-greet-sub b { color: var(--linq-ink); font-weight: 600; }

/* === Period segmented toggle ================================== */
.ld-period {
  margin: 0 16px 12px;
  display: flex; gap: 2px;
  padding: 3px;
  background: #E8E1D1;
  border-radius: 8px;
}
.ld-period-btn {
  flex: 1; padding: 7px 0;
  font: 500 12.5px 'Public Sans', 'Public Sans', system-ui, sans-serif;
  color: #8A857A;
  background: transparent;
  border: none; border-radius: 6px; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.ld-period-btn.is-active {
  background: #FFFFFF;
  color: var(--linq-ink);
  box-shadow: 0 1px 2px rgba(0,0,0,0.05);
  font-weight: 600;
}

/* === Filter chips (single-row, scroll-X) ====================== */
.ld-chips {
  display: flex; gap: 6px;
  margin: 0 0 12px;
  padding: 0 16px;
  overflow-x: auto;
  scrollbar-width: none;
}
.ld-chips::-webkit-scrollbar { display: none; }
.ld-chip {
  flex-shrink: 0;
  padding: 6px 12px;
  border-radius: 999px;
  background: #FFFFFF;
  border: 1px solid #D9D2C2;
  color: var(--linq-ink);
  font: 500 12px 'Public Sans', 'Public Sans', system-ui, sans-serif;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.ld-chip.is-active {
  background: var(--linq-ink);
  border-color: var(--linq-ink);
  color: #FFFFFF;
  font-weight: 600;
}

/* === Stacked bar (Active/Completed/Cancelled) ================ */
.ld-stack-bar {
  margin: 0 16px 12px;
  background: #FFFFFF;
  border: 1px solid #D9D2C2;
  border-radius: 10px;
  padding: 14px 16px 16px;
  text-decoration: none;
  display: block;
}
.ld-stack-bar-eyebrow {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 10px; font-weight: 700; letter-spacing: 0.14em;
  color: #8A857A;
  text-transform: uppercase;
  font-family: 'Archivo Narrow', sans-serif;
  margin-bottom: 10px;
}
.ld-stack-bar-eyebrow-period { color: var(--linq-ink); }
.ld-stack-bar-track {
  display: flex;
  width: 100%; height: 12px;
  border-radius: 6px;
  background: #E8E1D1;
  overflow: hidden;
}
.ld-stack-bar-seg {
  height: 100%;
  transition: flex-grow .25s ease;
}
/* Brand-aligned segment palette: ocean blue / sage green / brand red.
   Active = data secondary (Ocean), Completed = success (Sage), Cancelled = error (Bad).
   Signal orange is reserved for primary CTAs only — keeps the dashboard from shouting. */
.ld-stack-bar-seg--active    { background: var(--linq-blue); flex-grow: 0; }
.ld-stack-bar-seg--completed { background: var(--linq-green); flex-grow: 0; }
.ld-stack-bar-seg--cancelled { background: var(--linq-red); flex-grow: 0; }
.ld-stack-bar-legend {
  margin-top: 12px;
  display: grid; grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
}
.ld-stack-bar-leg { display: flex; flex-direction: column; gap: 3px; }
.ld-stack-bar-leg-row {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.10em;
  color: #8A857A; text-transform: uppercase;
  font-family: 'Archivo Narrow', sans-serif;
}
.ld-stack-bar-leg-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.ld-stack-bar-leg-dot--active    { background: var(--linq-blue); }
.ld-stack-bar-leg-dot--completed { background: var(--linq-green); }
.ld-stack-bar-leg-dot--cancelled { background: var(--linq-red); }
.ld-stack-bar-leg-num {
  font-size: 22px; font-weight: 600; letter-spacing: -0.02em;
  color: var(--linq-ink); line-height: 1.1;
  font-family: 'Archivo Narrow', sans-serif;
}

/* === Tablet 2-col rows ====================================== */
.ld-row-2col { display: contents; }
@media (min-width: 641px) and (max-width: 1023px) {
  .ld-row-2col {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin: 0 16px 12px;
  }
  .ld-row-2col > .ld-card { margin: 0 !important; }
}

/* === Stat pills row (3 light cards) ========================= */
.ld-stat-row {
  display: grid; grid-template-columns: 1fr 1fr 1fr;
  gap: 8px; padding: 0 16px 12px;
}
.ld-stat {
  background: #FFFFFF;
  border: 1px solid #D9D2C2;
  border-radius: 10px;
  padding: 11px 12px 12px;
}
.ld-stat-label {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: #A8A294;
  font-family: 'Archivo Narrow', sans-serif;
}
.ld-stat-num {
  margin-top: 4px;
  font-size: 22px; font-weight: 600; letter-spacing: -0.02em;
  color: var(--linq-ink);
  font-family: 'Archivo Narrow', sans-serif;
  line-height: 1.1;
}
/* Brand-kit secondaries — class names kept for back-compat with
   page partials shipped pre-rebrand. .ld-stat--teal now reads orange
   because the primary accent flipped from teal to Signal. */
.ld-stat--teal   .ld-stat-num { color: var(--linq-orange); } /* Signal */
.ld-stat--orange .ld-stat-num { color: var(--linq-orange); } /* Signal */
.ld-stat--green  .ld-stat-num { color: var(--linq-green); } /* Sage */
.ld-stat--red    .ld-stat-num { color: var(--linq-red); } /* Bad */
.ld-stat--ocean  .ld-stat-num { color: var(--linq-blue); } /* Ocean */
.ld-stat-foot {
  margin-top: 6px;
  font-size: 10px; color: #A8A294;
  font-family: 'Archivo Narrow', sans-serif;
  letter-spacing: 0.04em;
}

/* === Setup banner (soft cream-orange — was too yellow) ==== */
.ld-setup {
  margin: 0 16px 12px;
  background: linear-gradient(135deg, #FFF0E2, #FBE2D2);
  border: 1px solid #FFC9A3;
  border-radius: 10px;
  padding: 12px 14px;
  display: flex; align-items: center; gap: 12px;
  text-decoration: none; color: var(--linq-ink);
  -webkit-tap-highlight-color: transparent;
}
.ld-setup-icon {
  width: 32px; height: 32px; border-radius: 9px;
  background: rgba(234,106,44, 0.14); color: #C24E0E;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.ld-setup-main { flex: 1; min-width: 0; }
.ld-setup-title { font-size: 13px; font-weight: 600; color: #4A2410; }
.ld-setup-sub { font-size: 11.5px; color: #7A3E1F; margin-top: 2px; }
.ld-setup-pill {
  font-size: 10.5px; padding: 3px 8px;
  background: rgba(255, 251, 241, 0.7); border-radius: 4px;
  color: #4A2410; font-weight: 700;
  font-family: 'Archivo Narrow', sans-serif;
}

/* === Card chrome ============================================ */
.ld-card {
  margin: 0 16px 12px;
  background: #FFFFFF;
  border: 1px solid rgba(15,22,35,.10);
  border-radius: 12px;
  padding: 14px;
}

/* === Reverse card (.ld-card--ink) ===========================
   Ink-on-cream contrast surface. Use sparingly — at most one ink
   card per dashboard fold (two if one is the trial welcome). The
   nested `.ld-card--ink-2` is a slightly lifted child surface for
   sub-grids inside an ink parent (mirrors the marketing-site
   "How it works · One loop, four moves" layered cards). Eyebrow,
   numerals, and CTA recolor automatically. */
.ld-card--ink {
  background: var(--linq-ink);
  border-color: var(--linq-ink);
  color: var(--linq-cream);
  border-radius: 16px;
  padding: 28px;
}
.ld-card--ink .ld-card-h h3,
.ld-card--ink .ld-card-h .ld-card-pill { color: #A8A294; background: transparent; }
.ld-card--ink .ld-card-h .ld-card-link { color: var(--linq-orange); }
.ld-card--ink .ld-list-row,
.ld-card--ink .ld-list-title { color: var(--linq-cream); }
.ld-card--ink .ld-list-sub { color: rgba(242, 237, 226, 0.66); }
.ld-card--ink .ld-empty   { color: rgba(242, 237, 226, 0.55); }
/* Nested child card for grids inside an ink surface. */
.ld-card--ink-2 {
  background: var(--linq-ink-2);
  border: none;
  border-radius: 14px;
  padding: 24px;
  color: var(--linq-cream);
}

/* === Step-numeral card (.ld-step-card) ======================
   Numbered process tile — Signal mono numeral eyebrow, Bone headline,
   Bone-2 body. Used inside `.ld-card--ink` for sequential content
   (onboarding summaries, how-it-works style tiles). Mirrors the
   marketing site's `.dot-step` block. */
.ld-step-card {
  display: flex; flex-direction: column; gap: 8px;
}
.ld-step-card .ld-step-num {
  font-family: 'Archivo Narrow', sans-serif;
  font-size: 11px; font-weight: 600; letter-spacing: 0.10em;
  color: var(--linq-orange); text-transform: uppercase;
}
.ld-step-card .ld-step-h {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 18px; font-weight: 600; letter-spacing: -0.01em;
  color: var(--linq-cream); margin: 0;
}
.ld-step-card .ld-step-body {
  font-family: 'Public Sans', system-ui, sans-serif;
  font-size: 14px; line-height: 1.55;
  color: rgba(242, 237, 226, 0.66); margin: 0;
}
.ld-card-h {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.ld-card-h h3 {
  font-size: 11px; font-weight: 700; letter-spacing: 0.10em;
  text-transform: uppercase; color: #8A857A; margin: 0;
  font-family: 'Archivo Narrow', sans-serif;
}
.ld-card-h .ld-card-pill {
  font-size: 10.5px; padding: 2px 7px;
  background: #E8E1D1; border-radius: 4px;
  color: #8A857A; font-weight: 600;
  font-family: 'Archivo Narrow', sans-serif;
}
.ld-card-h .ld-card-link {
  font-size: 11px; color: var(--linq-orange); font-weight: 600;
  text-decoration: none;
  font-family: 'Archivo Narrow', sans-serif;
  letter-spacing: 0.04em;
}

/* === List rows ============================================== */
.ld-list { display: flex; flex-direction: column; gap: 6px; }
.ld-list-row {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 4px; border-radius: 8px;
  text-decoration: none; color: var(--linq-ink);
  -webkit-tap-highlight-color: transparent;
}
.ld-list-row:active { background: #E8E1D1; }
.ld-date-tile {
  width: 44px; padding: 6px 0; flex-shrink: 0;
  background: #E8E1D1; border-radius: 7px;
  text-align: center;
  font-family: 'Archivo Narrow', sans-serif;
}
.ld-date-tile-d { font-size: 9px; color: #A8A294; letter-spacing: 0.04em; text-transform: uppercase; }
.ld-date-tile-n { font-size: 15px; color: var(--linq-ink); font-weight: 600; line-height: 1.1; margin-top: 1px; }
.ld-list-tile {
  width: 36px; height: 36px; border-radius: 8px;
  background: #E8E1D1; color: #8A857A;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; font-size: 14px;
}
.ld-list-tile--brand { background: var(--linq-orange-lt); color: var(--linq-orange); }
.ld-list-main { flex: 1; min-width: 0; }
.ld-list-title { font-size: 13.5px; font-weight: 500; color: var(--linq-ink); line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ld-list-sub { font-size: 11px; color: #A8A294; margin-top: 1px; font-family: 'Archivo Narrow', sans-serif; }
.ld-list-amount {
  font-size: 13.5px; font-weight: 600; color: var(--linq-ink);
  font-family: 'Archivo Narrow', sans-serif;
  flex-shrink: 0;
}

/* === Status pills (canonical colour map · brand-aligned) ====
   Light backgrounds are tinted toward the brand's warm palette
   instead of cool greys; secondaries use Ocean (data) and Sage
   (success). Class names unchanged for back-compat. Callers can
   set `--dot-color` to colourise the leading status dot. */
.ld-pill {
  position: relative;
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 600; letter-spacing: 0.04em;
  padding: 6px 12px; border-radius: 999px; flex-shrink: 0;
  text-transform: uppercase;
}
.ld-pill::before {
  content: '';
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--dot-color, currentColor);
  flex-shrink: 0;
}
.ld-pill--pending      { background: #EFE8D9; color: #5C5749; }
.ld-pill--acceptance   { background: var(--linq-orange-lt); color: #A03700; }
.ld-pill--scheduled    { background: #D6E1F2; color: var(--linq-blue); }
.ld-pill--enroute      { background: #C2D4ED; color: #15396C; }
.ld-pill--onsite       { background: var(--linq-orange-lt); color: #A03700; }
.ld-pill--completed    { background: #E0E7CD; color: #3D5022; }
.ld-pill--cancelled    { background: #EFE8D9; color: #5C5749; }
.ld-pill--invoiced     { background: #D6E1F2; color: var(--linq-blue); }
.ld-pill--paid         { background: #E0E7CD; color: #3D5022; }
.ld-pill--unpaid       { background: var(--linq-orange-lt); color: #A03700; }
.ld-pill--overdue      { background: #F4D4CF; color: #7B1F15; }
.ld-pill--draft        { background: #EFE8D9; color: #5C5749; }
.ld-pill--sent         { background: #D6E1F2; color: var(--linq-blue); }
.ld-pill--accepted     { background: #E0E7CD; color: #3D5022; }
.ld-pill--declined     { background: #F4D4CF; color: #7B1F15; }
.ld-pill--unread       { background: var(--linq-orange-lt); color: var(--linq-orange); }
.ld-pill--replied      { background: #E0E7CD; color: #3D5022; }

/* === Activity feed rows ===================================== */
.ld-act { display: flex; gap: 11px; padding: 9px 4px; align-items: flex-start; text-decoration: none; -webkit-tap-highlight-color: transparent; }
.ld-act-tile {
  width: 28px; height: 28px; border-radius: 6px; background: #E8E1D1;
  display: flex; align-items: center; justify-content: center;
  color: #8A857A; flex-shrink: 0; margin-top: 1px;
}
.ld-act-main { flex: 1; min-width: 0; }
.ld-act-title { font-size: 12.5px; color: var(--linq-ink); line-height: 1.4; }
.ld-act-jobid { color: var(--linq-orange); font-weight: 600; font-family: 'Archivo Narrow', sans-serif; }
.ld-act-sub { font-size: 11px; color: #A8A294; margin-top: 1px; font-family: 'Archivo Narrow', sans-serif; }

/* === Empty state =========================================== */
.ld-empty {
  font-size: 12.5px; color: #A8A294;
  padding: 18px 6px; text-align: center;
}

/* === Form fields =========================================== */
.ld-field { margin: 0 16px 12px; }
.ld-field-label {
  display: block; margin-bottom: 6px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.10em;
  text-transform: uppercase; color: #8A857A;
  font-family: 'Archivo Narrow', sans-serif;
}
.ld-field-input,
.ld-field-textarea {
  width: 100%;
  background: #FFFFFF;
  border: 1px solid #D9D2C2;
  border-radius: 8px;
  padding: 10px 12px;
  font: 500 14px/1.4 'Public Sans', system-ui, sans-serif;
  color: var(--linq-ink);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.ld-field-input:focus,
.ld-field-textarea:focus {
  border-color: var(--linq-orange);
  box-shadow: 0 0 0 4px rgba(234,106,44,.20);
}
.ld-field-input::placeholder,
.ld-field-textarea::placeholder { color: #A8A294; }
.ld-field-textarea { resize: vertical; min-height: 80px; }

/* === CTA buttons =========================================== */
.ld-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px;
  padding: 14px 24px;
  border-radius: 999px;
  font: 600 13px 'Public Sans', system-ui, sans-serif;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
  -webkit-tap-highlight-color: transparent;
  transition: background .15s, border-color .15s;
}
.ld-btn--primary { background: var(--linq-orange); color: #FFFFFF; }
.ld-btn--primary:active { background: #E55A0E; }
.ld-btn--ink { background: var(--linq-ink); color: #FFFFFF; }
.ld-btn--ink:active { background: var(--linq-ink-2); }
.ld-btn--ghost {
  background: #FFFFFF;
  color: var(--linq-ink);
  border-color: #D9D2C2;
}
.ld-btn--ghost:active { background: #E8E1D1; }
.ld-btn--danger {
  background: #FFFFFF;
  color: var(--linq-red);
  border-color: #F4D4CF;
}
.ld-btn--danger:active { background: #F4D4CF; }

/* === Hide on >= 1024px (desktop only) ====================== */
@media (min-width: 1024px) {
  .ld-mobile { display: none !important; }
}

/* === Floating dialer (.fv-dialer-bubble) is fully retired ===
   The bottom-right softphone bubble was duplicating the topbar dialer
   button and competing with the FAB-menu corner. Hide it at every
   viewport — the topbar #fvDialerOpenTopbar button is now the single
   entry point for the dialer panel on desktop+tablet, and the side-
   drawer Quick Links opens it on mobile. The collapsed dialer
   container is also hidden so it stops occupying the bottom-right
   corner; only the expanded panel renders. */
.fv-dialer-bubble { display: none !important; }
#fv-dialer[data-collapsed="1"] { display: none !important; }

/* === Shared icon-tile token (.linq-action) ====================
   Codifies the qm-v1 / marketing-features icon look as one class so
   the menu FAB, Crew dock trigger, and any future action tiles all
   render identically: rounded-square Panel surface, 1px Ink-12%
   hairline, Ink glyph, and an optional offset Signal corner tab.

   Sizes:   .linq-action--sm  36×36 / 10px radius
            .linq-action--md  48×48 / 12px radius
            .linq-action--lg  56×56 / 14px radius   (default)

   Modifier: .linq-action--tab adds the offset Signal-orange square
             (8×8, 2px from each edge of the bottom-right corner).
             Reserved for the menu FAB and the Crew dock — do NOT
             apply elsewhere by default; the tab is a brand signal,
             not generic decoration.

   Light-mode only. The shared :hover state lifts to Bone-2; :active
   nudges 1px down for a tactile press. */
.linq-action {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 14px;
  background: var(--linq-off-white);         /* Panel */
  border: 1px solid rgba(15,22,35, 0.12);  /* Ink-12% hairline */
  color: var(--linq-ink);                            /* Ink glyph */
  box-shadow: 0 4px 14px rgba(15,22,35, 0.10);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background .15s ease, border-color .15s ease,
              box-shadow .15s ease, transform .12s ease;
  padding: 0;
  line-height: 1;
}
.linq-action:hover {
  background: #F7F3EA;                       /* Bone-soft / Bone-2 */
  border-color: rgba(15,22,35, 0.22);
}
.linq-action:active {
  transform: translateY(1px);
  box-shadow: 0 2px 8px rgba(15,22,35, 0.12);
}
.linq-action:focus-visible {
  outline: 2px solid var(--linq-orange);
  outline-offset: 2px;
}
.linq-action i,
.linq-action svg {
  display: block;
  font-size: 22px;
  line-height: 1;
  color: inherit;
}

/* Sizes ---------------------------------------------------------- */
.linq-action--sm { width: 36px; height: 36px; border-radius: 10px; }
.linq-action--sm i,
.linq-action--sm svg { font-size: 16px; }

.linq-action--md { width: 48px; height: 48px; border-radius: 12px; }
.linq-action--md i,
.linq-action--md svg { font-size: 20px; }

.linq-action--lg { width: 56px; height: 56px; border-radius: 14px; }
.linq-action--lg i,
.linq-action--lg svg { font-size: 22px; }

/* Tab modifier — RESERVED: menu FAB + Crew dock only ------------- */
.linq-action--tab::after {
  content: '';
  position: absolute;
  right: 2px;
  bottom: 2px;
  width: 8px;
  height: 8px;
  background: var(--linq-orange);                       /* Signal */
  border-radius: 2px;
  pointer-events: none;
}

/* === Heading-page tab strip (.page-tabs) ========================
   Reused by Jobs / Invoices / Estimates / Customers / Finance for
   their sub-view navigation. Pill-style per v1.0 brand guidelines
   page 8: radius 999, weight 600, soft cream/white surface, signal-
   orange active state. Public Sans inherited from body. */
.page-tabs {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 1rem 0;
  padding: 0;
  list-style: none;
}
.page-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.45rem 0.95rem;
  border-radius: var(--linq-r-pill);
  font-family: var(--linq-font-body);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  text-decoration: none;
  border: 1px solid rgba(15, 22, 35, 0.10);
  color: var(--linq-ink-soft);
  background: var(--linq-off-white);
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  white-space: nowrap;
}
.page-tab:hover {
  color: var(--linq-ink);
  border-color: rgba(15, 22, 35, 0.18);
  background: #FFFFFF;
}
.page-tab-on {
  color: var(--linq-orange);
  background: var(--linq-orange-lt);
  border-color: var(--linq-orange-lt);
}
.page-tab-on:hover {
  color: var(--linq-orange);
  background: var(--linq-orange-lt);
  border-color: var(--linq-orange);
}
.page-tab i {
  font-size: 0.95rem;
  line-height: 1;
}
.page-tab-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.1rem;
  padding: 0 0.35rem;
  border-radius: var(--linq-r-pill);
  font-family: var(--linq-font-mono);
  font-size: 0.6875rem;
  font-weight: 600;
  background: rgba(15, 22, 35, 0.06);
  color: var(--linq-ink-soft);
  letter-spacing: 0;
}
.page-tab-on .page-tab-count {
  background: rgba(234, 106, 44, 0.18);
  color: var(--linq-orange);
}
